﻿using System;
using System.Diagnostics;
using System.Drawing;

using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using OpenTK.Input;

namespace parts_client
{
	class PartsClient : GameWindow
	{
        protected Stopwatch _Stopwatch = new Stopwatch();
        protected int _NumFrames = 0;

		public PartsClient()
        {
            int x = DisplayDevice.Default.Bounds.Right + 1;
            int y = 0;
            int width = 3840;
            int height = 2160;
            this.Bounds = new Rectangle(x, y, width, height);

            this.OnResize(null);
		}

		protected override void OnLoad(EventArgs e)
		{
			base.OnLoad(e);

			GL.ClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            _Stopwatch.Start();
		}

		protected override void OnResize(EventArgs e)
		{
			base.OnResize(e);
			
            //GL.Viewport(this.ClientRectangle.X, this.ClientRectangle.Y,
            //    this.ClientRectangle.Width, this.ClientRectangle.Height);

			SimData data = SimData.GetCurData();
			if (data != null)
			{
				GL.PixelZoom((float)this.ClientRectangle.Width / (float)data.FrameWidth,
					         (float)this.ClientRectangle.Height / (float)data.FrameHeight);
                GL.RasterPos2(0, 0);
				GL.MatrixMode(MatrixMode.Projection);
				GL.LoadIdentity();
				GL.Ortho(0.0, data.FrameWidth, 0.0, data.FrameHeight, -1.0, 1.0);
				GL.MatrixMode(MatrixMode.Modelview);
			}
		}

		protected override void OnUpdateFrame(FrameEventArgs e)
		{
			base.OnUpdateFrame(e);

			if (Keyboard[Key.Escape])
				this.Exit();
		}

		protected override void OnRenderFrame(FrameEventArgs e)
		{
			base.OnRenderFrame(e);

			GL.Clear(ClearBufferMask.ColorBufferBit);

			SimData data = SimData.GetCurData();
			if (data != null)
			{
				GL.DrawPixels(data.FrameWidth, data.FrameHeight, PixelFormat.Rgba, PixelType.UnsignedByte, data.Frame);
				//for (int i = 0; i < data.N; i++)
				//{
				//	this.DrawParticle(data.X[i], data.Y[i], data.MinX, data.MaxX, data.MinY, data.MaxY);
				//}
			}

			SwapBuffers();

            _NumFrames++;
            if(_NumFrames % 100 == 0)
            {
                double avgFrameTime = _Stopwatch.ElapsedMilliseconds / 100.0;
                Debug.WriteLine("Drawing " + (1000.0 / avgFrameTime).ToString("n4") + " frames per second");
                _Stopwatch.Reset();
				_Stopwatch.Start();
            }
		}

		protected void DrawParticle(float x, float y, float minx, float maxx, float miny, float maxy)
		{
			float r = 0.5f;

			this.DrawCircle(x, y, r);

			if (x - r < minx)
				this.DrawCircle(x + (maxx - minx), y, r);
			else if (x + r > maxx)
				this.DrawCircle(x - (maxx - minx), y, r);

			if (y - r < miny)
				this.DrawCircle(x, y + (maxy - miny), r);
			else if (y + r > maxy)
				this.DrawCircle(x, y - (maxy - miny), r);
		}

		protected void DrawCircle(float x, float y, float r)
        {
			GL.Color3(1.0, 0.0, 0.0);
            GL.Begin(BeginMode.Triangles);
            {
                GL.Vertex2(x, y + r);
                GL.Vertex2(x - r, y - r);
                GL.Vertex2(x + r, y - r);
            }
            GL.End();
			
            //GL.Color3(1.0, 0.0, 0.0);
            //GL.Begin(BeginMode.Quads);
            //{
            //    GL.Vertex2(x + r, y + r);
            //    GL.Vertex2(x + r, y - r);
            //    GL.Vertex2(x - r, y - r);
            //    GL.Vertex2(x - r, y + r);
            //}
            //GL.End();
			
            //GL.Color3(0.0, 0.0, 1.0);
            //GL.Begin(BeginMode.Polygon);
            //{
            //    for (double theta = 0.0; theta < 2.0 * Math.PI; theta += Math.PI / 4.0)
            //    {
            //        GL.Vertex2(x + r * Math.Cos(theta), y + r * Math.Sin(theta));
            //    }
            //}
            //GL.End();

            //GL.Begin(BeginMode.LineLoop);
            //{
            //    GL.Color3(0.0, 1.0, 0.0);
            //    for (double theta = 0.0; theta < 2.0 * Math.PI; theta += Math.PI / 4.0)
            //    {
            //        GL.Vertex2(x + r * Math.Cos(theta), y + r * Math.Sin(theta));
            //    }
            //}
            //GL.End();
        }

		[STAThread]
		static void Main()
		{
			ServerConnection conn = new ServerConnection("tessy.umcs.maine.edu", 12345);
			if (conn.IsConnected)
			{
				PartsClient vis = new PartsClient();
				vis.Run();
			}
			conn.Close();
		}
	}
}
